const db = require('../config/database');
const fs = require('fs-extra');
const path = require('path');
const crypto = require('crypto');
const archiver = require('archiver');
const logger = require('../config/logger');

const UPLOAD_DIR = process.env.UPLOAD_DIR || path.join(__dirname, '../../uploads');

// 启动时记录上传目录
logger.info(`文件控制器 - UPLOAD_DIR: ${UPLOAD_DIR}`);

/**
 * 计算文件MD5
 */
function calculateMD5(filePath) {
  return new Promise((resolve, reject) => {
    const hash = crypto.createHash('md5');
    const stream = fs.createReadStream(filePath);

    stream.on('data', data => hash.update(data));
    stream.on('end', () => resolve(hash.digest('hex')));
    stream.on('error', reject);
  });
}

/**
 * 获取文件列表
 */
exports.getFileList = async (req, res) => {
  try {
    const { parentId, path: dirPath, userId, page = 1, limit = 20 } = req.query;
    const userType = req.user.type;
    const offset = (page - 1) * limit;

    let query = 'SELECT * FROM files WHERE is_deleted = 0';
    const params = [];

    // 如果提供了 path 参数，根据路径查找
    if (dirPath !== undefined) {
      // 根路径 '/' 同时兼容 parent_id = 0 或 NULL（历史数据可能为NULL）
      if (dirPath === '/' || dirPath === '') {
        query += ' AND (parent_id = 0 OR parent_id IS NULL)';
      } else {
        // 根据路径查找父目录
        const [parentDirs] = await db.query(
          'SELECT id FROM files WHERE file_path = ? AND is_directory = 1 AND is_deleted = 0',
          [dirPath]
        );
        
        if (parentDirs.length > 0) {
          query += ' AND parent_id = ?';
          params.push(parentDirs[0].id);
        } else {
          // 路径不存在，返回空列表
          return res.json({
            success: true,
            data: {
              files: [],
              total: 0,
              page: parseInt(page),
              limit: parseInt(limit)
            }
          });
        }
      }
    } else {
      // 使用 parentId 参数（默认为 0，即根目录），同时兼容 NULL
      if (!parentId || parentId === '0') {
        query += ' AND (parent_id = 0 OR parent_id IS NULL)';
      } else {
        query += ' AND parent_id = ?';
        params.push(parentId);
      }
    }

    // 普通用户：可以查看所有目录（is_directory=1），但文件仅限于自己的（user_id = 当前用户）
    if (userType === 'user') {
      query += ' AND (is_directory = 1 OR user_id = ?)';
      params.push(req.user.id);
    } else if (userId) {
      // 管理员可以查看指定用户的文件
      query += ' AND user_id = ?';
      params.push(userId);
    }

    // 获取总数
    const countQuery = query.replace('SELECT *', 'SELECT COUNT(*) as total');
    const [countResult] = await db.query(countQuery, params);
    const total = countResult[0].total;

    // 添加排序和分页
    query += ' ORDER BY is_directory DESC, file_name ASC LIMIT ? OFFSET ?';
    params.push(parseInt(limit), parseInt(offset));

    const [files] = await db.query(query, params);

    // 转换数据格式以匹配前端期望（保留原始字段名）
    const formattedFiles = files
      .filter(file => file.file_name !== 'chunks' && file.file_name !== '.Recycle_bin')  // 过滤掉 chunks 和 .Recycle_bin 文件夹
      .map(file => ({
        id: file.id,
        file_name: file.file_name,
        file_path: file.file_path,
        file_size: file.file_size,
        is_directory: file.is_directory,
        mime_type: file.mime_type,
        updated_at: file.updated_at,
        created_at: file.created_at,
        parent_id: file.parent_id,
        // 兼容旧格式
        name: file.file_name,
        path: file.file_path,
        size: file.file_size,
        isDirectory: file.is_directory,
        type: file.is_directory ? 'folder' : getFileType(file.mime_type),
        status: 'synced'
      }));

    res.json({
      success: true,
      data: {
        files: formattedFiles,
        total: total,
        page: parseInt(page),
        limit: parseInt(limit)
      }
    });
  } catch (error) {
    logger.error('获取文件列表失败:', error);
    res.status(500).json({
      success: false,
      message: '获取文件列表失败'
    });
  }
};

/**
 * 根据MIME类型获取文件类型
 */
function getFileType(mimeType) {
  if (!mimeType) return 'file';

  if (mimeType.startsWith('image/')) return 'image';
  if (mimeType.startsWith('video/')) return 'video';
  if (mimeType.startsWith('audio/')) return 'audio';
  if (mimeType.includes('pdf') || mimeType.includes('document') ||
      mimeType.includes('word') || mimeType.includes('excel') ||
      mimeType.includes('powerpoint')) return 'document';

  return 'file';
}

/**
 * 创建文件夹
 */
exports.createFolder = async (req, res) => {
  try {
    const { name, parentId, parent_path } = req.body;
    const userId = req.user.type === 'user' ? req.user.id : null;

    if (!name) {
      return res.status(400).json({
        success: false,
        message: '文件夹名称不能为空'
      });
    }

    // 获取父目录ID（支持parent_path和parentId两种方式）
    let actualParentId = parentId || 0;
    if (parent_path && parent_path !== '/') {
      const [parentDirs] = await db.query(
        'SELECT id FROM files WHERE file_path = ? AND is_directory = 1 AND is_deleted = 0',
        [parent_path]
      );
      if (parentDirs.length > 0) {
        actualParentId = parentDirs[0].id;
      }
    }

    // 检查同名文件夹
    const [existing] = await db.query(
      'SELECT id FROM files WHERE file_name = ? AND parent_id = ? AND is_directory = 1 AND is_deleted = 0',
      [name, actualParentId]
    );

    if (existing.length > 0) {
      return res.status(400).json({
        success: false,
        message: '文件夹已存在'
      });
    }

    // 构建文件路径
    let filePath = name;
    if (parent_path && parent_path !== '/') {
      filePath = path.join(parent_path, name);
    } else if (actualParentId > 0) {
      const [parent] = await db.query('SELECT file_path FROM files WHERE id = ?', [actualParentId]);
      if (parent.length > 0) {
        filePath = path.join(parent[0].file_path, name);
      }
    } else {
      filePath = `/${name}`;
    }

    // 创建物理目录
    const fullPath = path.join(UPLOAD_DIR, filePath);
    await fs.ensureDir(fullPath);

    // 插入数据库
    const [result] = await db.query(
      'INSERT INTO files (file_name, file_path, parent_id, is_directory, user_id) VALUES (?, ?, ?, 1, ?)',
      [name, filePath, actualParentId, userId]
    );

    logger.info(`创建文件夹: ${filePath}`);

    res.json({
      success: true,
      message: '文件夹创建成功',
      data: {
        id: result.insertId,
        file_name: name,
        file_path: filePath
      }
    });
  } catch (error) {
    logger.error('创建文件夹失败:', error);
    res.status(500).json({
      success: false,
      message: '创建文件夹失败'
    });
  }
};

/**
 * 批量删除文件/文件夹
 */
exports.batchDeleteFiles = async (req, res) => {
  try {
    const { ids } = req.body;

    if (!ids || !Array.isArray(ids) || ids.length === 0) {
      return res.status(400).json({
        success: false,
        message: '请选择要删除的文件'
      });
    }

    logger.info(`批量删除请求 - 数量: ${ids.length}, IDs: ${ids.join(', ')}`);

    let successCount = 0;
    let failCount = 0;
    const errors = [];

    // 逐个删除文件
    for (const id of ids) {
      try {
        // 检查文件是否存在
        const [files] = await db.query('SELECT * FROM files WHERE id = ?', [id]);
        if (files.length === 0) {
          logger.warn(`文件不存在，跳过 - ID: ${id}`);
          failCount++;
          errors.push(`文件ID ${id} 不存在`);
          continue;
        }

        const file = files[0];

        // 普通用户只能删除自己的文件
        if (req.user.type === 'user' && file.user_id !== req.user.id) {
          logger.warn(`无权删除文件: ${file.file_name}`);
          failCount++;
          errors.push(`无权删除 ${file.file_name}`);
          continue;
        }

        // 删除物理文件/文件夹
        const relativePath = file.file_path.startsWith('/') ? file.file_path.substring(1) : file.file_path;
        const physicalPath = path.join(UPLOAD_DIR, relativePath);
        const absolutePath = path.resolve(physicalPath);

        try {
          if (await fs.pathExists(absolutePath)) {
            if (file.is_directory) {
              await fs.remove(absolutePath);
              logger.info(`已删除文件夹及其内容: ${absolutePath}`);
            } else {
              await fs.unlink(absolutePath);
              logger.info(`已删除文件: ${absolutePath}`);
            }
          }
        } catch (fsError) {
          logger.error(`删除物理文件失败: ${absolutePath}`, fsError);
          // 继续执行数据库删除
        }

        // 如果是文件夹，先递归删除所有子文件的数据库记录
        if (file.is_directory) {
          await deleteChildrenRecursive(id, true); // true = 硬删除
        }

        // 完全删除数据库记录（硬删除）
        await db.query('DELETE FROM files WHERE id = ?', [id]);
        logger.info(`已完全删除文件记录: ${file.file_path}`);

        successCount++;
      } catch (error) {
        logger.error(`删除文件失败 - ID: ${id}`, error);
        failCount++;
        errors.push(`删除文件ID ${id} 失败`);
      }
    }

    // 返回结果
    const message = `成功删除 ${successCount} 个文件${failCount > 0 ? `，失败 ${failCount} 个` : ''}`;
    logger.info(`批量删除完成 - ${message}`);

    res.json({
      success: true,
      message,
      data: {
        total: ids.length,
        success: successCount,
        failed: failCount,
        errors: errors.length > 0 ? errors : undefined
      }
    });
  } catch (error) {
    logger.error('批量删除失败:', error);
    res.status(500).json({
      success: false,
      message: '批量删除失败'
    });
  }
};

/**
 * 删除文件/文件夹（软删除 + 物理删除）
 */
exports.deleteFile = async (req, res) => {
  try {
    const { id } = req.params;

    logger.info(`删除请求 - 文件ID: ${id}`);

    // 检查文件是否存在（包括已删除的）
    const [files] = await db.query('SELECT * FROM files WHERE id = ?', [id]);
    if (files.length === 0) {
      logger.error(`文件记录不存在 - ID: ${id}`);
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    const file = files[0];
    logger.info(`找到文件记录: ${file.file_name}, 路径: ${file.file_path}`);

    // 普通用户只能删除自己的文件
    if (req.user.type === 'user' && file.user_id !== req.user.id) {
      return res.status(403).json({
        success: false,
        message: '无权删除此文件'
      });
    }

    // 删除物理文件/文件夹
    const relativePath = file.file_path.startsWith('/') ? file.file_path.substring(1) : file.file_path;
    const physicalPath = path.join(UPLOAD_DIR, relativePath);
    const absolutePath = path.resolve(physicalPath);

    logger.info(`准备删除物理路径: ${absolutePath}`);

    try {
      if (await fs.pathExists(absolutePath)) {
        if (file.is_directory) {
          // 删除文件夹及其所有内容
          await fs.remove(absolutePath);
          logger.info(`已删除文件夹及其内容: ${absolutePath}`);
        } else {
          // 删除单个文件
          await fs.unlink(absolutePath);
          logger.info(`已删除文件: ${absolutePath}`);
        }
      } else {
        logger.warn(`物理文件不存在，跳过删除: ${absolutePath}`);
      }
    } catch (fsError) {
      logger.error(`删除物理文件失败: ${absolutePath}`, fsError);
      // 继续执行数据库删除，即使物理删除失败
    }

    // 如果是文件夹，先递归删除所有子文件的数据库记录
    if (file.is_directory) {
      await deleteChildrenRecursive(id, true); // true = 硬删除
    }

    // 完全删除数据库记录（硬删除）
    await db.query('DELETE FROM files WHERE id = ?', [id]);
    logger.info(`已完全删除文件记录: ${file.file_path}`);

    res.json({
      success: true,
      message: '删除成功'
    });
  } catch (error) {
    logger.error('删除文件失败:', error);
    res.status(500).json({
      success: false,
      message: '删除文件失败'
    });
  }
};

/**
 * 递归删除子文件（物理文件已由父文件夹删除一起处理）
 * @param {number} parentId - 父文件夹ID
 * @param {boolean} hardDelete - 是否硬删除（完全删除数据库记录）
 */
async function deleteChildrenRecursive(parentId, hardDelete = true) {
  const [children] = await db.query('SELECT id, file_name, is_directory FROM files WHERE parent_id = ?', [parentId]);

  for (const child of children) {
    if (hardDelete) {
      // 完全删除数据库记录
      await db.query('DELETE FROM files WHERE id = ?', [child.id]);
      logger.info(`已完全删除子文件记录: ${child.file_name} (ID: ${child.id})`);
    } else {
      // 软删除（标记为已删除）
      await db.query('UPDATE files SET is_deleted = 1 WHERE id = ?', [child.id]);
      logger.info(`标记子文件为已删除: ${child.file_name} (ID: ${child.id})`);
    }
    
    // 如果是子文件夹，递归处理
    if (child.is_directory) {
      await deleteChildrenRecursive(child.id, hardDelete);
    }
  }
}

/**
 * 重命名文件/文件夹
 */
exports.renameFile = async (req, res) => {
  try {
    const { id } = req.params;
    const { newName } = req.body;

    // 检查文件是否存在
    const [files] = await db.query('SELECT * FROM files WHERE id = ?', [id]);
    if (files.length === 0) {
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    const file = files[0];

    // 普通用户只能重命名自己的文件
    if (req.user.type === 'user' && file.user_id !== req.user.id) {
      return res.status(403).json({
        success: false,
        message: '无权重命名此文件'
      });
    }

    // 检查同名文件
    const [existing] = await db.query(
      'SELECT id FROM files WHERE file_name = ? AND parent_id = ? AND id != ? AND is_deleted = 0',
      [newName, file.parent_id, id]
    );

    if (existing.length > 0) {
      return res.status(400).json({
        success: false,
        message: '文件名已存在'
      });
    }

    // 构建新路径
    const oldPath = path.join(UPLOAD_DIR, file.file_path);
    const parentPath = path.dirname(file.file_path);
    const newFilePath = parentPath === '.' ? newName : path.join(parentPath, newName);
    const newPath = path.join(UPLOAD_DIR, newFilePath);

    // 重命名物理文件/文件夹
    if (await fs.pathExists(oldPath)) {
      await fs.move(oldPath, newPath);
    }

    // 更新数据库
    await db.query(
      'UPDATE files SET file_name = ?, file_path = ? WHERE id = ?',
      [newName, newFilePath, id]
    );

    logger.info(`重命名文件: ${file.file_path} -> ${newFilePath}`);

    res.json({
      success: true,
      message: '重命名成功'
    });
  } catch (error) {
    logger.error('重命名文件失败:', error);
    res.status(500).json({
      success: false,
      message: '重命名文件失败'
    });
  }
};

/**
 * 复制文件/文件夹
 */
exports.copyFile = async (req, res) => {
  try {
    const { id } = req.params;
    const { targetParentId } = req.body;

    // 检查源文件
    const [files] = await db.query('SELECT * FROM files WHERE id = ?', [id]);
    if (files.length === 0) {
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    const sourceFile = files[0];

    // 构建目标路径
    let targetPath = sourceFile.file_name;
    if (targetParentId > 0) {
      const [parent] = await db.query('SELECT file_path FROM files WHERE id = ?', [targetParentId]);
      if (parent.length > 0) {
        targetPath = path.join(parent[0].file_path, sourceFile.file_name);
      }
    }

    // 复制物理文件
    const sourcePath = path.join(UPLOAD_DIR, sourceFile.file_path);
    const destPath = path.join(UPLOAD_DIR, targetPath);

    if (await fs.pathExists(sourcePath)) {
      await fs.copy(sourcePath, destPath);
    }

    // 插入数据库
    const [result] = await db.query(
      'INSERT INTO files (file_name, file_path, file_size, file_hash, mime_type, parent_id, is_directory, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
      [sourceFile.file_name, targetPath, sourceFile.file_size, sourceFile.file_hash, sourceFile.mime_type, targetParentId, sourceFile.is_directory, sourceFile.user_id]
    );

    logger.info(`复制文件: ${sourceFile.file_path} -> ${targetPath}`);

    res.json({
      success: true,
      message: '复制成功',
      data: {
        id: result.insertId
      }
    });
  } catch (error) {
    logger.error('复制文件失败:', error);
    res.status(500).json({
      success: false,
      message: '复制文件失败'
    });
  }
};

/**
 * 移动文件/文件夹
 */
exports.moveFile = async (req, res) => {
  try {
    const { id } = req.params;
    const { targetParentId } = req.body;

    // 检查源文件
    const [files] = await db.query('SELECT * FROM files WHERE id = ?', [id]);
    if (files.length === 0) {
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    const sourceFile = files[0];

    // 构建目标路径
    let targetPath = sourceFile.file_name;
    if (targetParentId > 0) {
      const [parent] = await db.query('SELECT file_path FROM files WHERE id = ?', [targetParentId]);
      if (parent.length > 0) {
        targetPath = path.join(parent[0].file_path, sourceFile.file_name);
      }
    }

    // 移动物理文件
    const sourcePath = path.join(UPLOAD_DIR, sourceFile.file_path);
    const destPath = path.join(UPLOAD_DIR, targetPath);

    if (await fs.pathExists(sourcePath)) {
      await fs.move(sourcePath, destPath);
    }

    // 更新数据库
    await db.query(
      'UPDATE files SET file_path = ?, parent_id = ? WHERE id = ?',
      [targetPath, targetParentId, id]
    );

    logger.info(`移动文件: ${sourceFile.file_path} -> ${targetPath}`);

    res.json({
      success: true,
      message: '移动成功'
    });
  } catch (error) {
    logger.error('移动文件失败:', error);
    res.status(500).json({
      success: false,
      message: '移动文件失败'
    });
  }
};

/**
 * 下载文件
 */
exports.downloadFile = async (req, res) => {
  try {
    const { id } = req.params;

    logger.info(`下载请求 - 文件ID: ${id}`);

    // 检查文件
    const [files] = await db.query('SELECT * FROM files WHERE id = ? AND is_deleted = 0', [id]);
    if (files.length === 0) {
      logger.error(`文件不存在 - ID: ${id}`);
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    const file = files[0];
    logger.info(`找到文件记录: ${file.file_name}, 路径: ${file.file_path}`);

    if (file.is_directory) {
      return res.status(400).json({
        success: false,
        message: '不能下载文件夹'
      });
    }

    // 移除file_path开头的斜杠，确保路径正确拼接
    const relativePath = file.file_path.startsWith('/') ? file.file_path.substring(1) : file.file_path;
    logger.info(`UPLOAD_DIR: ${UPLOAD_DIR}`);
    logger.info(`file.file_path: ${file.file_path}`);
    logger.info(`relativePath: ${relativePath}`);
    
    const filePath = path.join(UPLOAD_DIR, relativePath);
    logger.info(`filePath (joined): ${filePath}`);
    
    const absolutePath = path.resolve(filePath);
    logger.info(`absolutePath (resolved): ${absolutePath}`);

    if (!await fs.pathExists(absolutePath)) {
      logger.error(`物理文件不存在: ${absolutePath}`);
      return res.status(404).json({
        success: false,
        message: `物理文件不存在: ${file.file_name}`
      });
    }

    // 设置正确的文件名编码，支持中文
    const encodedFileName = encodeURIComponent(file.file_name);
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodedFileName}`);
    res.setHeader('Content-Type', file.mime_type || 'application/octet-stream');
    
    // 使用 sendFile，必须使用绝对路径
    res.sendFile(absolutePath, (err) => {
      if (err) {
        logger.error('发送文件失败:', err);
        if (!res.headersSent) {
          res.status(500).json({
            success: false,
            message: '下载文件失败'
          });
        }
      } else {
        logger.info(`下载文件: ${file.file_path}`);
      }
    });
  } catch (error) {
    logger.error('下载文件失败:', error);
    res.status(500).json({
      success: false,
      message: '下载文件失败'
    });
  }
};

/**
 * 递归获取文件夹中的所有文件
 */
async function getFilesInDirectory(fileId, basePath = '') {
  const allFiles = [];
  
  logger.info(`递归查询文件夹 ID: ${fileId}, basePath: ${basePath}`);
  
  // 查询当前文件夹下的所有子文件
  const [children] = await db.query(
    'SELECT * FROM files WHERE parent_id = ? AND is_deleted = 0',
    [fileId]
  );
  
  logger.info(`找到 ${children.length} 个子项`);
  
  for (const child of children) {
    const childPath = basePath ? `${basePath}/${child.file_name}` : child.file_name;
    
    logger.info(`子项 - ID: ${child.id}, 名称: ${child.file_name}, 类型: ${child.is_directory ? '文件夹' : '文件'}, childPath: ${childPath}`);
    
    if (child.is_directory) {
      // 递归处理子文件夹
      const subFiles = await getFilesInDirectory(child.id, childPath);
      allFiles.push(...subFiles);
    } else {
      // 添加文件
      const relativePath = child.file_path.startsWith('/') ? child.file_path.substring(1) : child.file_path;
      const filePath = path.join(UPLOAD_DIR, relativePath);
      const absolutePath = path.resolve(filePath);
      
      logger.info(`子文件 - file_path: ${child.file_path}, 绝对路径: ${absolutePath}, ZIP路径: ${childPath}`);
      
      if (await fs.pathExists(absolutePath)) {
        allFiles.push({
          name: childPath,
          path: absolutePath
        });
        logger.info(`添加到ZIP: ${childPath} <- ${absolutePath}`);
      } else {
        logger.warn(`文件不存在: ${absolutePath}`);
      }
    }
  }
  
  return allFiles;
}

/**
 * 批量下载文件（打包成ZIP，支持文件夹）
 */
exports.batchDownload = async (req, res) => {
  try {
    const { fileIds } = req.body;

    if (!fileIds || !Array.isArray(fileIds) || fileIds.length === 0) {
      return res.status(400).json({
        success: false,
        message: '请选择要下载的文件'
      });
    }

    logger.info(`批量下载请求 - 数量: ${fileIds.length}, IDs: ${fileIds.join(', ')}`);

    // 查询所有选中的文件/文件夹
    // 使用多个占位符
    const placeholders = fileIds.map(() => '?').join(',');
    const [files] = await db.query(
      `SELECT * FROM files WHERE id IN (${placeholders}) AND is_deleted = 0`,
      fileIds
    );
    
    logger.info(`数据库查询返回 ${files.length} 条记录`);

    if (files.length === 0) {
      return res.status(404).json({
        success: false,
        message: '未找到有效的文件'
      });
    }

    logger.info(`找到 ${files.length} 个项目（文件/文件夹）`);
    
    // 打印查询到的文件信息
    files.forEach(f => {
      logger.info(`选中项 - ID: ${f.id}, 名称: ${f.file_name}, 类型: ${f.is_directory ? '文件夹' : '文件'}, 路径: ${f.file_path}`);
    });

    // 收集所有要打包的文件
    const allFiles = [];
    
    for (const file of files) {
      if (file.is_directory) {
        // 递归获取文件夹中的所有文件
        logger.info(`处理文件夹: ${file.file_name} (ID: ${file.id})`);
        const folderFiles = await getFilesInDirectory(file.id, file.file_name);
        allFiles.push(...folderFiles);
        logger.info(`文件夹 ${file.file_name} 包含 ${folderFiles.length} 个文件`);
      } else {
        // 直接添加文件
        const relativePath = file.file_path.startsWith('/') ? file.file_path.substring(1) : file.file_path;
        const filePath = path.join(UPLOAD_DIR, relativePath);
        const absolutePath = path.resolve(filePath);

        logger.info(`处理文件 - 名称: ${file.file_name}, file_path: ${file.file_path}, 绝对路径: ${absolutePath}`);

        if (await fs.pathExists(absolutePath)) {
          allFiles.push({
            name: file.file_name,
            path: absolutePath
          });
          logger.info(`添加文件到ZIP: ${file.file_name} -> ${absolutePath}`);
        } else {
          logger.warn(`文件不存在: ${absolutePath}`);
        }
      }
    }

    if (allFiles.length === 0) {
      return res.status(404).json({
        success: false,
        message: '没有找到可下载的文件'
      });
    }

    logger.info(`准备打包 ${allFiles.length} 个文件`);
    
    // 打印最终要添加到ZIP的文件列表
    logger.info('=== ZIP文件列表 ===');
    allFiles.forEach((file, index) => {
      logger.info(`[${index + 1}] ZIP内路径: ${file.name} <- 物理路径: ${file.path}`);
    });
    logger.info('==================');

    // 设置响应头
    const zipName = `files_${Date.now()}.zip`;
    res.setHeader('Content-Type', 'application/zip');
    res.setHeader('Content-Disposition', `attachment; filename*=UTF-8''${encodeURIComponent(zipName)}`);

    // 创建zip归档
    const archive = archiver('zip', {
      zlib: { level: 9 } // 压缩级别
    });

    // 处理错误
    archive.on('error', (err) => {
      logger.error('创建ZIP失败:', err);
      if (!res.headersSent) {
        res.status(500).json({
          success: false,
          message: '创建压缩包失败'
        });
      }
    });

    // 监听进度
    archive.on('progress', (progress) => {
      logger.info(`ZIP进度: ${progress.entries.processed}/${progress.entries.total}`);
    });

    // 完成时记录
    archive.on('end', () => {
      logger.info(`批量下载完成: ${zipName}, 总大小: ${archive.pointer()} bytes`);
    });

    // 管道到响应
    archive.pipe(res);

    // 添加文件到归档（保持文件夹结构）
    for (const file of allFiles) {
      logger.info(`正在添加到ZIP: ${file.name}`);
      archive.file(file.path, { name: file.name });
    }

    // 完成归档
    await archive.finalize();

  } catch (error) {
    logger.error('批量下载失败:', error);
    if (!res.headersSent) {
      res.status(500).json({
        success: false,
        message: '批量下载失败'
      });
    }
  }
};

/**
 * 获取文件信息
 */
exports.getFileInfo = async (req, res) => {
  try {
    const { id } = req.params;

    const [files] = await db.query('SELECT * FROM files WHERE id = ? AND is_deleted = 0', [id]);
    if (files.length === 0) {
      return res.status(404).json({
        success: false,
        message: '文件不存在'
      });
    }

    res.json({
      success: true,
      data: files[0]
    });
  } catch (error) {
    logger.error('获取文件信息失败:', error);
    res.status(500).json({
      success: false,
      message: '获取文件信息失败'
    });
  }
};

/**
 * 检查文件是否已存在（根据MD5）
 */
exports.checkFileExists = async (req, res) => {
  try {
    const { fileName, md5 } = req.body;
    const userId = req.user.id;

    const [files] = await db.query(
      'SELECT id, file_path FROM files WHERE file_hash = ? AND user_id = ? AND is_deleted = 0 LIMIT 1',
      [md5, userId]
    );

    res.json({
      success: true,
      exists: files.length > 0,
      fileId: files.length > 0 ? files[0].id : null
    });
  } catch (error) {
    logger.error('检查文件存在失败:', error);
    res.status(500).json({
      success: false,
      message: '检查文件存在失败'
    });
  }
};

/**
 * 秒传功能（文件已存在则直接引用）
 */
exports.quickUpload = async (req, res) => {
  try {
    const { fileName, md5, fileSize, parentPath = '/' } = req.body;
    const userId = req.user.id;

    // 检查文件是否已存在
    const [existingFiles] = await db.query(
      'SELECT id, file_path FROM files WHERE file_hash = ? AND is_deleted = 0 LIMIT 1',
      [md5]
    );

    if (existingFiles.length === 0) {
      return res.json({
        success: false,
        message: '文件不存在，需要正常上传'
      });
    }

    const existingFile = existingFiles[0];

    // 获取父目录ID
    let parentId = 0;
    if (parentPath !== '/') {
      const [parentDirs] = await db.query(
        'SELECT id FROM files WHERE file_path = ? AND user_id = ? AND is_directory = 1 AND is_deleted = 0',
        [parentPath, userId]
      );
      if (parentDirs.length > 0) {
        parentId = parentDirs[0].id;
      }
    }

    // 创建新的文件记录（引用已存在的物理文件）
    const newFilePath = parentPath === '/' ? `/${fileName}` : `${parentPath}/${fileName}`;

    const [result] = await db.query(
      `INSERT INTO files (file_name, file_path, file_size, file_hash, user_id, parent_id, is_directory, mime_type, created_at, updated_at)
       VALUES (?, ?, ?, ?, ?, ?, 0, ?, NOW(), NOW())`,
      [fileName, newFilePath, fileSize, md5, userId, parentId, 'application/octet-stream']
    );

    logger.info(`秒传成功: ${fileName}, MD5: ${md5}`);

    res.json({
      success: true,
      message: '秒传成功',
      data: {
        fileId: result.insertId,
        filePath: newFilePath
      }
    });
  } catch (error) {
    logger.error('秒传失败:', error);
    res.status(500).json({
      success: false,
      message: '秒传失败'
    });
  }
};

/**
 * 同步FTP上传的文件记录到数据库
 */
exports.syncFileRecord = async (req, res) => {
  try {
    const { fileName, filePath, fileSize, action } = req.body;
    const userId = req.user.id;

    if (action === 'upload') {
      // 检查文件是否已存在
      const [existing] = await db.query(
        'SELECT id FROM files WHERE file_path = ? AND user_id = ? AND is_deleted = 0',
        [filePath, userId]
      );

      if (existing.length > 0) {
        // 更新文件记录
        await db.query(
          'UPDATE files SET file_size = ?, updated_at = NOW() WHERE id = ?',
          [fileSize, existing[0].id]
        );
        logger.info(`更新文件记录: ${filePath}`);
      } else {
        // 创建新文件记录
        const parentPath = path.dirname(filePath);
        let parentId = 0;

        if (parentPath !== '/' && parentPath !== '.') {
          const [parentDirs] = await db.query(
            'SELECT id FROM files WHERE file_path = ? AND is_directory = 1 AND is_deleted = 0',
            [parentPath]
          );
          if (parentDirs.length > 0) {
            parentId = parentDirs[0].id;
          }
        }

        await db.query(
          `INSERT INTO files (file_name, file_path, file_size, user_id, parent_id, is_directory)
           VALUES (?, ?, ?, ?, ?, 0)`,
          [fileName, filePath, fileSize, userId, parentId]
        );
        logger.info(`创建文件记录: ${filePath}`);
      }

      res.json({
        success: true,
        message: '文件记录已同步'
      });
    } else {
      res.status(400).json({
        success: false,
        message: '不支持的操作'
      });
    }
  } catch (error) {
    logger.error('同步文件记录失败:', error);
    res.status(500).json({
      success: false,
      message: '同步文件记录失败'
    });
  }
};
